module fcgi.Conduit;

private import  fcgi.Request;
private import  fcgi.Protocol;

private import  tango.io.device.Conduit;

class FastCGIConduit : Conduit
{
    FastCGIRequest request_;
    FastCGIStreamType streamType_;
    char[][] queuedData_;
    bool reader_;
    bool endOfFile_;

    this (FastCGIRequest request, FastCGIStreamType streamType, bool reader)
    {
        reader_ = reader;
        request_ = request;
        streamType_ = streamType;
    }
    
    public void reset ()
    {
        queuedData_ = [];
        endOfFile_ = false;
    }
    
    package void setEndOfFile ()
    {
        endOfFile_ = true;
    }

    package bool isEndOfFile ()
    {
      return endOfFile_;
    }
    
    package void pushData (char[] data)
    {
        queuedData_ ~= data;
    }
    
    size_t read (void[] dst)
    {
        if (!reader_ || endOfFile_)
            return Conduit.Eof;
      
        int written = 0;
        while (written < dst.length)
        {
            if (queuedData_.length > 0)
            {
                int copy = queuedData_[0].length;

                // have more than we need?
                if (copy > dst.length - written)
                        copy = dst.length - written;

                // copy slice
                dst[written .. written + copy] = cast(void[]) queuedData_[0][0 .. copy];

                // copied everything?
                if (copy == queuedData_[0].length)
                    queuedData_ = queuedData_[1 .. $];
                else
                    queuedData_[0] = queuedData_[0][copy .. $];

                // we've got it
                written += copy;
            }
            else
            {
                // get it from request, it'll read it from socket
                int result = request_.read(streamType_, cast(char[]) dst[written .. $]);
                // got something
                if (result > 0)
                {
                    written += result;
                }
                else
                {
                    // have read something, so return it
                    if (written > 0)
                        return written;
                    // nothing read in this loop, so end of stream
                    else
                        return Eof;
                }
            }
        }
    
        return written;
    }
    
    size_t write (void[] src)
    {
        if (reader_)
            return src.length;
        return request_.write(streamType_, cast(char[]) src);
    }

    void disconnect ()
    {

    }
    
    size_t bufferSize ()
    {
        return 1024;
    }
    /*    
    Handle fileHandle()
    {
            return 0;
	    }*/

    void detach ()
    {

    }

    char[] toString ()
    {
        return "FastCGIConduit";
    }
}
